package zhangxinhua.JavaDesignDetails.components.model;

import lombok.Data;
import zhangxinhua.JavaDesignDetails.发布订阅者模式.ISubscribe;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @package zhangxinhua.JavaDesignDetails.components.model
 * @Class SubscribePublish
 * @Description 发布订阅消息载体
 * @Author zhangxinhua
 * @Date 19-10-24 下午2:29
 */
@Data
public class SubscribePublish<T> {
    /**
     * 订阅器名称
     */
    private String name;
    /**
     * 订阅器队列容量
     */
    private int QUEUE_CAPACITY = 20;

    /**
     * 订阅器存储队列
     */
    private BlockingQueue<Msg> queue = new ArrayBlockingQueue<Msg>(QUEUE_CAPACITY);
    /**
     * 订阅者
     */
    private List<ISubscribe> subcribers = new ArrayList<ISubscribe>();

    public SubscribePublish(String name) {
        this.name = name;
    }

    public void publish(String publisher, T message, boolean isInstantMsg) {
        if (isInstantMsg) {
            update(publisher, message);
            return;
        }
        Msg<T> m = new Msg<T>(publisher, message);
        if (!queue.offer(m)) {
            update();
        }
    }

    public void subcribe(ISubscribe subcriber) {
        subcribers.add(subcriber);
    }

    public void unSubcribe(ISubscribe subcriber) {
        subcribers.remove(subcriber);
    }

    public void update() {
        Msg m = null;
        while ((m = queue.poll()) != null) {
            this.update(m.getPublisher(), (T) m.getMsg());
        }
    }

    public void update(String publisher, T Msg) {
        for (ISubscribe subcriber : subcribers) {
            subcriber.update(publisher, Msg);
        }
    }
}
